package org.ofbiz.autoconfig.auto;

import com.alibaba.fastjson.JSON;
import javolution.util.FastList;
import javolution.util.FastMap;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ReportServices {
    public static final String module = ReportServices.class.getName();

    public static Map<String, Object> executeGraphReport(DispatchContext dctx, Map<String, ? extends Object> context) {

	Map<String, Object> result = ServiceUtil.returnSuccess();
	LocalDispatcher dispatcher = dctx.getDispatcher();
	Delegator delegator = dctx.getDelegator();
	GenericValue userLogin =(GenericValue) context.get("userLogin");
		String serviceParametersStr = (String) context.get("serviceParameters");
		Map serviceParameters = new HashMap();
	Debug.log("param ==== "+serviceParametersStr);
	try {
		if(UtilValidate.isNotEmpty(serviceParametersStr)){
			serviceParameters = JSON.parseObject(serviceParametersStr, HashMap.class);
		}
	    String reportSql = "";
	    String reportChartSql2 = "";
	    String reportChartSql3 = "";
	    String reportTableSql = "";
	    String reportTableSql2 = "";
	    String reportName = "";
	    
	    String chartServiceName1 = "";
	    String chartServiceName2 = "";
	    String tableServiceName1 = "";
	    String tableServiceName2 = "";

	    String chartServiceName1Para = "";
	    String chartServiceName2Para = "";
	    String tableServiceName1Para = "";
	    String tableServiceName2Para = "";

	    
	    String id = (String) context.get("id");
	    GenericValue entity = delegator.findOne("OnlGraphReport", UtilMisc.toMap("id", id), false);
	    if (UtilValidate.isNotEmpty(entity)) {
		reportName = entity.getString("reportName");
		reportSql = entity.getString("reportSql");
		reportChartSql2 = entity.getString("reportChartSql2");
		reportChartSql3 = entity.getString("reportChartSql3");
		reportTableSql = entity.getString("reportTableSql");
		reportTableSql2 = entity.getString("reportTableSql2");
		
		chartServiceName1 = entity.getString("chartServiceName1");
		chartServiceName2 = entity.getString("chartServiceName2");
		tableServiceName1 = entity.getString("tableServiceName1");
		tableServiceName2 = entity.getString("tableServiceName2");

		chartServiceName1Para = entity.getString("chartServiceName1Para");
		chartServiceName2Para = entity.getString("chartServiceName2Para");
		tableServiceName1Para = entity.getString("tableServiceName1Para");
		tableServiceName2Para = entity.getString("tableServiceName2Para");

		
		
	    }

	    result.put("reportName", reportName);

	    //List chartData = new ArrayList();
	    List chartData2 = new ArrayList();
	    List chartData3 = new ArrayList();
	    List itemList = new ArrayList();
	    List itemList2 = new ArrayList();

	    if (UtilValidate.isNotEmpty(reportSql)) {
	    	Map r1 =getChartData(delegator,reportSql);
	    	result.put("chartData", r1.get("chartData"));
	    	result.put("chartDataList", r1.get("chartDataList"));
	    	result.put("chartDataKeyList", r1.get("chartDataKeyList"));
	    	
	    }
	    if (UtilValidate.isNotEmpty(reportChartSql2)) {
	    	Map r2 =getChartData(delegator,reportChartSql2);
	    	result.put("chartData2", r2.get("chartData"));
	    	result.put("chartDataList2", r2.get("chartDataList"));
	    	result.put("chartDataKeyList2", r2.get("chartDataKeyList"));
	    	
	    }
	    if (UtilValidate.isNotEmpty(reportChartSql3)) {
	    	Map r3 =getChartData(delegator,reportChartSql3);
	    	result.put("chartData3", r3.get("chartData"));
	    	result.put("chartDataList3", r3.get("chartDataList"));
	    	result.put("chartDataKeyList3", r3.get("chartDataKeyList"));
	    	
	    }
	   
	   

	    if (UtilValidate.isNotEmpty(reportTableSql)) {
	    	Map r1Table =getTableData(delegator, reportTableSql);
	    	result.put("itemList", r1Table.get("itemList"));	
	    	result.put("itemListTable", r1Table.get("itemListTable"));// 记录
	    	result.put("itemListKeyList",r1Table.get("itemListKeyList"));// 列名
	    }
	    if (UtilValidate.isNotEmpty(reportTableSql2)) {
	    	Map r2Table =getTableData(delegator, reportTableSql2);
	    	result.put("itemList2", r2Table.get("itemList"));	
	    	result.put("itemListTable2", r2Table.get("itemListTable"));// 记录
	    	result.put("itemListKeyList2",r2Table.get("itemListKeyList"));// 列名
	    }
	    
	    if (UtilValidate.isEmpty(reportSql)&&UtilValidate.isNotEmpty(chartServiceName1)) {
	    	Map r1 =getChartDataByService(userLogin,dispatcher,chartServiceName1,chartServiceName1Para,serviceParameters);
	    	result.put("chartData", r1.get("chartData"));
	    	result.put("chartDataList", r1.get("chartDataList"));
	    	result.put("chartDataKeyList", r1.get("chartDataKeyList"));
	    	
	    }
	    if (UtilValidate.isEmpty(reportSql)&&UtilValidate.isNotEmpty(chartServiceName2)) {
	    	Map r2 =getChartDataByService(userLogin,dispatcher,chartServiceName2,chartServiceName2Para,serviceParameters);
	    	result.put("chartData2", r2.get("chartData"));
	    	result.put("chartDataList2", r2.get("chartDataList"));
	    	result.put("chartDataKeyList2", r2.get("chartDataKeyList"));
	    	
	    }
	    if (UtilValidate.isEmpty(reportTableSql)&&UtilValidate.isNotEmpty(tableServiceName1)) {
	    	Map r1Table =getChartDataByService(userLogin,dispatcher,tableServiceName1,tableServiceName1Para,serviceParameters);
	    	result.put("itemList", r1Table.get("itemList"));	
	    	result.put("itemListTable", r1Table.get("itemListTable"));// 记录
	    	result.put("itemListKeyList",r1Table.get("itemListKeyList"));// 列名
	    }
	    if (UtilValidate.isEmpty(reportTableSql2)&&UtilValidate.isNotEmpty(tableServiceName2)) {
	    	Map r2Table =getChartDataByService(userLogin,dispatcher,tableServiceName2,tableServiceName2Para,serviceParameters);
	    	result.put("itemList2", r2Table.get("itemList"));	
	    	result.put("itemListTable2", r2Table.get("itemListTable"));// 记录
	    	result.put("itemListKeyList2",r2Table.get("itemListKeyList"));// 列名
	    }
	    
	    
	    

	} catch (GenericEntityException e) {
	    Debug.logError(e.getMessage(), module);

	} catch (GenericServiceException e) {
		Debug.logError(e.getMessage(), module);
	}
	return result;
    }
    
    private static Map getChartDataByService(GenericValue userLogin,LocalDispatcher dispatcher,
    		String chartServiceName1,String chartServiceName1Para
		,Map<String, ? extends Object> context) throws GenericServiceException{
    	Map result =new HashMap();
    	List chartData = new ArrayList();
    	List chartDataKeyList = new ArrayList();
    	List chartDataList = new ArrayList();
    	
//    	reportSql =reportSql.trim();
		Map service_context = UtilMisc.toMap("userLogin", userLogin);
		if(UtilValidate.isNotEmpty(chartServiceName1Para)){
			String[] split = chartServiceName1Para.split(",");
			for (String s : split) {
				if(UtilValidate.isNotEmpty(s)){
					Debug.log("getChartDataByService param"+s);
					Object value =  context.get(s);
					service_context.put(s,value);
				}
			}
		}
		Map sercice_result = dispatcher.runSync(chartServiceName1, service_context);
		Debug.log("sercice_result = " +sercice_result);
		Map<String,Object> workMap = (Map<String, Object>) sercice_result.get("workMap");
		if(UtilValidate.isNotEmpty(workMap)){
			return workMap;
		}
		chartDataList= (List) sercice_result.get("records");// 记录
		chartDataKeyList = (List) sercice_result.get("columns");// 列名
//
		List records1 = (List) sercice_result.get("records");
		for (int i = 0; i < records1.size(); i++) {
			Object object = records1.get(i);
			if(object instanceof List){
				Map map = new HashMap();
			    List subList = (List) records1.get(i);
			    map.put("key", subList.get(0));
			    map.put("value", subList.get(1));
			    chartData.add(map);
			}
		    
		}
		result.put("chartData", chartData);
		result.put("chartDataList", chartDataList);// 记录
		result.put("chartDataKeyList", chartDataKeyList);// 列名
		return result;
    }
    
    private static Map getChartData(Delegator delegator,String reportSql){
    	Map result =new HashMap();
    	List chartData = new ArrayList();
    	List chartDataKeyList = new ArrayList();
    	List chartDataList = new ArrayList();
    	
    	reportSql =reportSql.trim();
    	Map service_context = UtilMisc.toMap("sqlCommand", reportSql);
		Map sercice_result = EntitySQLProcessor.executeQuery(delegator, service_context);
		chartDataList= (List) sercice_result.get("records");// 记录
		chartDataKeyList = (List) sercice_result.get("columns");// 列名

		List records1 = (List) sercice_result.get("records");
		for (int i = 0; i < records1.size(); i++) {
		    Map map = new HashMap();
		    List subList = (List) records1.get(i);
		    map.put("key", subList.get(0));
		    map.put("value", subList.get(1));
		    chartData.add(map);
		}
		result.put("chartData", chartData);
		result.put("chartDataList", chartDataList);// 记录
		result.put("chartDataKeyList", chartDataKeyList);// 列名
		return result;
    }
    
    
    private static Map getTableData(Delegator delegator,String reportTableSql) {
    	Debug.log("reportTableSql" + reportTableSql);
    	Map result =new HashMap();
    	List itemList = new ArrayList();
    	List itemListKeyList = new ArrayList();
    	List itemListTable = new ArrayList();

    	reportTableSql =reportTableSql.trim();
    		Map table_context = UtilMisc.toMap("sqlCommand", reportTableSql);
    		Map table_result = EntitySQLProcessor.executeQuery(delegator, table_context);
    		Debug.log("table_result"+  table_result);
    		itemListTable= (List) table_result.get("records");// 记录
    		itemListKeyList= (List) table_result.get("columns");// 列名

    		Debug.log("itemListTable"+ itemListTable);
    		Debug.log("itemListKeyList"+  itemListKeyList);

    		List records_item = (List) table_result.get("records");
    		List columns_item = (List) table_result.get("columns");
    		for (int i = 0; i < records_item.size(); i++) {
    			Object object = records_item.get(i);
    			 if(object instanceof List) {
	    		    Map map = new HashMap();
	    		    List valueList = (List) records_item.get(i);
	    		    for (int j = 0; j < columns_item.size(); j++) {
	    			map.put(columns_item.get(j), valueList.get(j));
	    		    }
	    		    itemList.add(map);
    			}
    		}
    		result.put("itemList", itemList);// 
    		result.put("itemListKeyList", itemListKeyList);// 列名
    		result.put("itemListTable", itemListTable);// 记录
    		
    		return result;
    	
    	    
    }
	public static String listToString2(List list, String separator) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < list.size(); i++) {
			sb.append(list.get(i)).append(separator);
		}
		return list.isEmpty() ? "" : sb.toString().substring(0, sb.toString().length() - 1);
	}

    /**
     * 导出
     */

    public static Map<String, Object> exportXlsGraphReport(DispatchContext dctx,
	    Map<String, ? extends Object> context) {
	Delegator delegator = dctx.getDelegator();
		LocalDispatcher dispatcher = dctx.getDispatcher();
		GenericValue userLogin =(GenericValue) context.get("userLogin");

	Map<String, Object> result = ServiceUtil.returnSuccess();
	String serviceParametersStr = (String) context.get("serviceParameters");
	Map serviceParameters = new HashMap();
Debug.log("param ==== "+serviceParametersStr);
	try {

	    String id = (String) context.get("id");
	    String reportField = (String) context.get("reportField");
	    GenericValue entity = delegator.findOne("OnlGraphReport", UtilMisc.toMap("id", id), false);

	    String reportTableSql = entity.getString("reportTableSql");
	    String tableServiceName1Para = entity.getString("tableServiceName1Para");
	    if(UtilValidate.isNotEmpty(serviceParametersStr)){
			serviceParameters = JSON.parseObject(serviceParametersStr, HashMap.class);
		}
	    if (UtilValidate.isNotEmpty(reportField)) {
	    	reportTableSql = entity.getString(reportField);
		    }
		String tableServiceName1 = entity.getString("tableServiceName1");
		if (UtilValidate.isEmpty(reportTableSql)&& UtilValidate.isNotEmpty(tableServiceName1)) {
			Map r1Table =getChartDataByService(userLogin,dispatcher,tableServiceName1,tableServiceName1Para,serviceParameters);
			result.put("list", r1Table.get("itemList"));
			List<String> chartDataKeyList = (List<String>) r1Table.get("itemListKeyList");
			String headers = listToString2(chartDataKeyList, ",");
			Map<String, Object> keyMap = FastMap.newInstance();
			for (int i=0;i<chartDataKeyList.size();i++ ) {
				keyMap.put(String.valueOf(i), chartDataKeyList.get(i));
			}
			result.put("keyMap", keyMap);// 记录
			result.put("headers",headers);// 列名
			Debug.log("result"+result);
			return result;
	    }

	    Map table_context = UtilMisc.toMap("sqlCommand", reportTableSql);
	    Map table_result = EntitySQLProcessor.executeQuery(delegator, table_context);

	    List records = (List) table_result.get("records");
	    List columns = (List) table_result.get("columns");

	    List<Map<String, Object>> list = FastList.newInstance();
	    Map<String, Object> keyMap = FastMap.newInstance();

	    String headers = "";
	    for (int i = 0; i < columns.size(); i++) {
		if (i > 0) {
		    headers = headers + ",";
		}
		headers = headers + (String) columns.get(i);
		Map map = new HashMap();
		keyMap.put(String.valueOf(i), columns.get(i));

	    }
	    result.put("headers", headers);

	    for (int i = 0; i < records.size(); i++) {
		Map map = new HashMap();
		List valueList = (List) records.get(i);
		for (int j = 0; j < columns.size(); j++) {

		    if (UtilValidate.isEmpty(valueList.get(j))) {
			map.put(columns.get(j), "");
		    } else {
			map.put(columns.get(j), valueList.get(j));
		    }

		}
		list.add(map);
	    }

	    result.put("list", list);
	    result.put("keyMap", keyMap);

	} catch (GenericEntityException | GenericServiceException e) {
	    Debug.logError(e.getMessage(), module);
	}
	return result;
    }

}
